var zm = zm||{};
zm.langs = {
	"pagebar": {
        "first": "&lt;&lt;",
        "pre": "&lt;",
        "next": "&gt;",
        "last": "&gt;&gt;",
        "pageSizePrefix": "每页",
        "pageSizeSuffix": "条",
        "info": "显示{1}-{2}条 共{0}条"
    },
    "data": {
        "nodata": "无数据...",
        "loading": "正在加载中...",
        "errorLoading":"与后台联系错误"
    }
};

(function($) {
	String.format = function() {
		var s = arguments[0];
		for (var i = 0; i < arguments.length - 1; i++) {
			var reg = new RegExp("\\{" + i + "\\}", "gm");
			s = s.replace(reg, arguments[i + 1])
		}
		return s
	};
	$.fn.grid = function(config) {
		var self = this;
		self.store = {
			data: {}
		};
		config = $.extend({
			pageOptions: [10, 20, 50, 100, 200],
			title: false,
			curPage: 1,
			totalPage: 1,
			sm: false,
			stripeRows: true,
			autoHeight: false,
			bbar:true,
			height: 450
		},config);
		var id = this.id;
		

		config.params = $.extend({
			start: 0,
			limit: 20
		},config.params);
		self.initConfig = config;
		config.perPage = config.params.limit;
		self.view = {
			topbar: '<div class="zm-grid-topbar" id="topbar_'+id+'"></div>',
			pagebar: '<div class="zm-grid-pagebar" id="pagebar_'+id+'"></div>',
			grid: {
				thead: '<div class="zm-grid-thead" id="thead_'+id+'"></div>',
				tbody: '<div class="zm-grid-tbody" id="tbody_'+id+'"></div>'
			},
			noData: '<div style="color:red;line-height:40px;text-align:center;" id="noData_'+id+'">' + zm.langs.data.nodata + '</div>',
			page: {
				first: '<a class="js-page-first XXX" href="javascript:void(0)" id="pageFirst_'+id+'">' + zm.langs.pagebar.first + '</a>',
				prev: '<a class="js-page-pre XXX" href="javascript:void(0)" id="pagePrev_'+id+'">' + zm.langs.pagebar.pre + '</a>',
				next: '<a class="js-page-next XXX" href="javascript:void(0)" id="pageNext_'+id+'">' + zm.langs.pagebar.next + '</a>',
				last: '<a class="js-page-last XXX" href="javascript:void(0)" id="pageLast_'+id+'">' + zm.langs.pagebar.last + '</a>',
				pageInfo: zm.langs.pagebar.info,
				number: '<a href="javascript:void(0)" class="js-page-number" id="number_'+id+'">{0}</a>',
				refresh: '<b id="refresh_'+id+'">&nbsp;</b>',
				curNumber: '<em id="current_'+id+'">{0}</em>'
			}
		};

		$(self).html('<div class="zm-grid" id="js_grid_root_'+id+'"></div>');
		self.view.table = $('#js_grid_root_'+id);
		self.view.table.html(self.view.topbar+String.format('<div class="zm-grid-wrap" id="js_grid_wrap_'+id+'" style="overflow:auto;">{0}{1}</div>',self.view.grid.thead,self.view.grid.tbody)+self.view.pagebar);
		self.view.topbar = $('#topbar_'+id);
		self.view.grid.thead = $('#thead_'+id);
		self.view.grid.tbody = $('#tbody_'+id);
		self.view.pagebar = $('#pagebar_'+id);
		self.view.grid.wrap = $('#js_grid_wrap_'+id);

		function initTopBar() {
			var strBar = '';
			if (config.tbar) {
				for (var i = 0,len=config.tbar.length; i < len; i++) {
					var bar = config.tbar[i];
					if(typeof(bar) == 'string') {
						strBar += bar;
					} else {
						strBar += '<' + (bar.tag || 'button') + ' id="topbar_action_'+i+'_'+id+'" href="#" type="'+(bar.btnType||'button')+'" class="zm-grid-topbar-button ' + (bar.cls ? bar.cls: '') + '" style="' + (bar.style ? bar.style: '') + '">' + (bar.text || '') + '</' + (bar.tag || 'button') + '>';
					}
				};
				self.view.topbar.html(strBar);
				for (var i = 0,len=config.tbar.length; i < len; i++) {
					var bar = config.tbar[i];
					if(typeof(bar) != 'string') {
						$('#topbar_action_'+i+'_'+id).on('click',bar.handler);
					}
				};
			}
			if(!strBar) {
				self.view.topbar.css('height','0px');
			}
		};
		var hasFilter = false,fixWidth=0;
		function _header() {
			var strHeader = '<ol class="zm-grid-header" id="js_grid_header_'+id+'">';
			var strFilter = '';
			var strCol = '';
			if (config.sm) {
				fixWidth += 30;
				strHeader += '<li style="width:20px;"><input  class="zm-grid-column-sm" type="checkbox" name="zm-item" id="header_sm_'+id+'"></input></th>';
				strFilter += '<li style="width:20px"></li>';
			}
			
			for(var i=0; i<config.columns.length; i++){
				var col = config.columns[i];
				var w = col.width ? col.width: 100;
				var expandColumnCls = '';
				if(col.autoWidth) {
					expandColumnCls='zm-grid-column-expand';
				} else {
					fixWidth += parseInt(w)+10;
				}
				strHeader += '<li style="width:'+w+'px" class="'+expandColumnCls+'">' + col.header + '</li>';
				if (col.filter) {
					if(col.filter.options) {
						var strOpts = [];
						for (var j = 0,len = col.filter.options.length; j < len; j++) {
							var opt = col.filter.options[j];
							strOpts.push('<option value="'+opt[0]+'">'+opt[1]+'</option>');
						};
						strFilter += '<li style="width:'+w+'px" class="zm-grid-column-filter '+expandColumnCls+'"><div><select class="filter-field" name="'+ (col.filter.name || col.dataIndex) +'">'+ strOpts.join('') + '</select></div></li>';
					} else {
						strFilter += '<li style="width:'+w+'px" class="zm-grid-column-filter '+expandColumnCls+'"><div><input class="filter-field" type="text" name="' + (col.filter.name || col.dataIndex) + '"><span class="filter-search"></span></div></li>';
						hasFilter = true;
					}
				} else {
					strFilter += '<li style="width:'+w+'px" class="'+expandColumnCls+'"></li>';
				}
			}
			strHeader += '</ol>';
			if (hasFilter) {
				strHeader += '<ol>' + strFilter + '</ol>';
			}
		
			self.view.grid.thead.html(strHeader);
			if (config.sm) {
				$('#header_sm_'+id).on('click',function() {
					if (this.checked) {
						$.each($('.zm-grid-column-sm', self.view.grid.tbody),function(i,el) {
							el.checked = true;
							el.parentTag('ul').addClass('row_selected');
						});
					} else {
						$.each($('.zm-grid-column-sm', self.view.grid.tbody),function(i,el) {
							el.checked = false;
							el.parentTag('ul').removeClass('row_selected');
						});
					}
				});
				self.getCheckedRowRecords = function() {
					var rec = [];
					$.each($('.zm-grid-column-sm', self.view.grid.tbody),function(i,el) {
						if(el.checked) {
							rec.push(self.store.data.items[cbRow.value]);
						}
					});
					return rec;
				}
			}
			if (hasFilter) {
				$.each($('.zm-grid-column-filter', self.view.grid.thead),function(i,el) {
					el.on('keydown',function(e) {
						if (!e)
					        e = window.event;
					    var code = e.keyCode;
					    if (e.charCode && code == 0)
					          code = e.charCode;
					    if (code == 13) {
							resetConfigParam();
							self.store.load();
						} else if (code == 27) {
							$('.filter-field', self.view.grid.thead).val('');
							resetConfigParam();
							self.store.load();
						}
					}).on('mouseenter',function() {
						$('.filter-search',this).show();
					}).on('mouseout',function() {
						$('.filter-search',this).hide();
					});
					
				});
				$.each($('.filter-search', self.view.grid.thead),function(i,el) {
					el.on('click',function() {
						resetConfigParam();
						self.store.load();
					});
				});
				$.each($('select', self.view.grid.thead),function(i,el) {
					el.on('change',function() {
						resetConfigParam();
						self.store.load();
					});
				});
			}
		};
		function _body() {
			var strBody = '';
			if (self.store.data.totalCount > 0) {
				$.each(self.store.data.items,
				function(i, el) {
					var rowCls = '';
					if(i%2==0) rowCls=' class="row_odd"';
					strBody += '<ul'+rowCls+' id="grid_row_'+i+'_'+id+'">';
					if (config.sm) {
						strBody += '<li style="width:20px" id="grid_row_'+i+'_column_sm_'+id+'"><input class="zm-grid-column-sm" type="checkbox" name="zm-item' + i + '" value="' + i + '"></input></li>'
					}
					for(var j=0; j<config.columns.length;j++){
						var col = config.columns[j];
						var val = col.dataIndex != '' ? eval('(el.' + col.dataIndex + ')') : '';
						var w = col.width ? col.width: 100;
						var expandColumnCls = '',clsArr=[],cls='';
						if(col.autoWidth) expandColumnCls='zm-grid-column-expand';
						if(expandColumnCls!=''){
							clsArr.push(expandColumnCls);
						};
						if(col.type == 'action'){
							clsArr.push('_gridAction');
						}
						if(col.cls){
							clsArr.push(col.cls);
						}
						if(clsArr.length>0){
							cls=' class="'+clsArr.join(' ')+'"';
						}
						strBody += '<li id="grid_row_'+i+'_column_'+j+'_'+id+'" style="width:'+w+'px;" '+cls+'>' + (col.renderer ? col.renderer(val, el) : val) + '</li>'
					}
					strBody += '</ul>'
				})
			} else {
				strBody += String.format(self.view.noData, config.columns.length + (config.sm ? 1 : 0))
			}
			self.view.grid.tbody.html(strBody);
			if (self.store.data.totalCount > 0) {
				$.each(self.store.data.items,
				function(i, el) {
					$.each(config.columns,
					function(index, obj) {
						if (obj.afterrender) {
							var val = obj.dataIndex != '' ? eval('(el.' + obj.dataIndex + ')') : '';
							var tdEl = $('#grid_row_'+i+'_column_'+index+'_'+id, trEl);
							var trEl = $('#grid_row_'+i+'_'+id);
							obj.afterrender(val, el, tdEl, trEl, self.view.table)
						}
					})
				})
			}
			$.each($('._gridAction', self.view.grid.tbody),function(i,el) {
				el.on('click',function(e) {
					var t = e.target;
					if (t.tagName === 'A' || t.tagName === 'BUTTON') {
						var rowEl =  $(this).parentTag('ul');
						var rowIndex = parseInt(rowEl.id.replace('grid_row_',''));
						var r = self.store.data.items[rowIndex];
						var action = t.title || t.href.substring(t.href.indexOf('#') + 1);
						self[action] && self[action](r,rowEl,rowIndex);
					}
				});
			});
			$.each($('ul', self.view.grid.tbody),function(i,el) {
				el.on('dblclick',function(e) {
					var rowIndex = parseInt(this.id.replace('grid_row_',''));
					var r = self.store.data.items[rowIndex];
					var action = 'fireDetail';
					self[action] && self[action](r);
				});
			});

			if (config.sm) {
				$.each($('.zm-grid-column-sm', self.view.grid.tbody),function(i,el) {
					el.on('click',function() {
						if (this.checked) {
							$(this).parentTag('ul').addClass('row_selected')
						} else {
							$(this).parentTag('ul').removeClass('row_selected')
						}
					});
				});
			}
			self.expandColumn();
		};

		function updatePagebar() {
			var strPage = '';
			var pagePanel = document.createElement("DIV");
			self.store.data = self.store.data || {};
			self.store.data.items = self.store.data.items || [];
			if(config.bbar) {
					var cp = parseInt(config.curPage);
					var pp = parseInt(config.perPage);
					var tp = parseInt(config.totalPage);
					
					var strPage = self.view.page.first.replace('XXX',cp > 1 ? '' : 'disabled');
					strPage += self.view.page.prev.replace('XXX',cp > 1 ? '' : 'disabled');
					var start = ((cp - 2) < 1 || tp <= 5) ? 1 : ((cp+2 < tp) ? (cp - 2) : Math.max(1,tp-5));
					var end = (start + 4) < tp ? (start + 5) : tp;
					var strNumber = '';
					for (var i = start; i <= end; i++) {
						if (i == cp) {
							strNumber += String.format(self.view.page.curNumber, i);
							continue;
						}
						strNumber += String.format(self.view.page.number, i)
					}
					strPage += strNumber;
					strPage += self.view.page.next.replace('XXX',cp < tp ? '' : 'disabled');
					strPage += self.view.page.last.replace('XXX',cp < tp ? '' : 'disabled');
			}
		
			pagePanel.innerHTML = strPage;
			
			var _el_b = document.createElement("B");
			_el_b.innerHTML = '&nbsp;';
			pagePanel.appendChild(_el_b);
			_el_b.onclick = function() {
				self.store.load();
			};

			//init  page size
			if(config.bbar) {
				var s = document.createElement("SELECT");
				for(var i=0; i<config.pageOptions.length;i++){
					var v = config.pageOptions[i];
					if(config.perPage == v){
						opt = new Option(v,v,true);
					}else{
						opt = new Option(v,v);
					}
					
					s.options.add(opt);
				}
				s.onchange = function(){
					config.curPage = 1;
					config.perPage = this.value;
					config.params.limit = config.perPage;
					updatePage();
				};
			};

			self.view.pagebar.html('');

			if(s) {
				pagePanel.appendChild(document.createTextNode(zm.langs.pagebar.pageSizePrefix));
				pagePanel.appendChild(s);
				var textNode = document.createTextNode(zm.langs.pagebar.pageSizeSuffix);
				pagePanel.appendChild(textNode);
			}

			self.view.pagebar.appendChild(pagePanel);
			self.view.pagebar.appendChild(document.createTextNode(String.format(self.view.page.pageInfo, self.store.data.totalCount||0, config.params.start + 1, config.params.start + self.store.data.items.length)));
		};
		self.view.pagebar.on('click',function(e) {
			if($(e.target).hasClass('disabled')) return;
			switch (e.target.className.replace(' ','')) {
			case 'js-page-first':
				config.curPage = 1;
				break;
			case 'js-page-pre':
				config.curPage -= 1;
				break;
			case 'js-page-next':
				config.curPage = config.curPage - 0 + 1;
				break;
			case 'js-page-last':
				config.curPage = (self.store.data.totalCount == 0 ? 1 : Math.ceil(self.store.data.totalCount / config.perPage));
				break;
			case 'js-page-number':
				config.curPage = e.target.textContent || e.target.outerText - 0;
				break;
			default:
				return false;
			}
			updatePage();
			e.preventDefault();
			e.stopPropagation()
		});
		function updatePage() {
			config.params.start = (config.curPage - 1) * config.perPage;
			self.store.load();
		};
		function init() {
			initTopBar();
			_header();
			updatePagebar();
			self.refreshView();
	
			var _el = self;
			while(parseInt(_el.css('width')) == 0||!(_el.css('display')=='block')) {
				_el = _el.parent();

			};

			self.wrapWidth = _el.css('width');

			var w = Math.max(fixWidth+120,self.wrapWidth);
			self.view.grid.thead.css('width',w);
			self.view.grid.tbody.css('width',w);
		};
		self.expandColumn = function(){
			if($('.zm-grid-column-expand',self).length > 0)
				var w = Math.max(100,$('#js_grid_header_'+id).zmwidth()-fixWidth-35);
				$.each($('.zm-grid-column-expand',self),function(i,el) {
					el.zmwidth(w);
				});
		}
		$(window).on('resize',function(){self.expandColumn();if(config.autoHeight) self.refreshView();});
		
		self.refreshView = function() {
			var height = config.height;
			if(config.autoHeight) {
				height = window.innerHeight;
			}
			var h = height-self.view.grid.thead.zmheight(true)-self.view.topbar.zmheight(true);
			if(config.bbar) {
				h -= self.view.pagebar.zmheight(true);
			}
			self.view.grid.tbody.zmheight(h);
		};
		self.store.load = function(cfg) {
			self.view.table.mask(zm.langs.data.loading);
			cfg = cfg || {};
			self.url = cfg.url || self.url || config.url;
			var filterParams = {};
			if (hasFilter) {
				$('.filter-field', self.view.grid.thead).each(function(i, el) {
					if (el.value != '') {
						filterParams[el.name] = el.value;
					}
				});
			}
			var params = $.extend({},
			config.params, cfg.params, self.baseParams, filterParams);
			$.ajax({
				url: self.url,
				params: params,
				success: function(data) {
					self.store.data = data;
					config.totalPage = data.totalCount > 0 ? Math.ceil(data.totalCount / config.perPage) : 1;
					_body();
					updatePagebar();
					self.view.table.unMask();
				},
				error: function(XMLHttpRequest, textStatus, errorThrown) {
					alert(zm.langs.data.errorLoading);
					self.view.table.unMask();
				}
			});
		};
		function resetConfigParam() {
			config.curPage = 1;
			config.params.start = 0;
		}
		self.config = config;
		init();
		return this;
	}
})($Z);